import { BUNDLE_TYPE_ENUM, EVENT_NAME_ENUM, UI_TYPE_ENUM } from "../base/EnumIndex";
import Singleton from "../base/Singleton";
import { Tools } from "../common/Tools";
import { EventManager } from "./EventManager";
import { ResManager } from "./ResManager";
const blockLayerName = "BlockLayer";
const blockGameLayerName = "BlockGameLayer";
const loadLayerName = "LoadLayer";

interface IUI {
    node: cc.Node,
    type: UI_TYPE_ENUM
}

export class UIManager extends Singleton {
    static get ins() {
        return super.getInstance<UIManager>();
    }

    /** ui栈 */
    private uiStack: Array<IUI> = [];
    /** 阻隔全屏触摸层 */
    private blockLayer: cc.Node = null;
    /** 阻隔游戏内触摸层 */
    private blockGameLayer: cc.Node = null;
    /** loading层 */
    private loadLayer: cc.Node = null;

    /** 显示加载页 */
    async showLoading() {
        this.enabledClick(false);
        this.show("LoadGameUI", UI_TYPE_ENUM.LOAD, BUNDLE_TYPE_ENUM.MAIN, false);
    }
    /** 关闭加载页 */
    closeLoading() {
        if (!this.loadLayer)
            this.loadLayer = this.getUIParent(UI_TYPE_ENUM.LOAD);
        if (this.loadLayer.children.length == 0) return;
        let LoadGameUINode = this.loadLayer.children[this.loadLayer.children.length - 1];
        if (LoadGameUINode) {
            cc.tween(LoadGameUINode)
                .to(0.2, { opacity: 0 })
                .call(() => LoadGameUINode.destroy())
                .start();
        }
    }
    /** 显示游戏内页面 */
    async showLevelPre(name: string) {
        this.enabledClick(false);
        let prefab = await ResManager.ins.loadRes(name, cc.Prefab, BUNDLE_TYPE_ENUM.MAIN);
        let type = UI_TYPE_ENUM.UI;
        let node = cc.instantiate(prefab);
        node.parent = this.getUIParent(type);

        this.uiStack.push({ node, type });
        this.enabledClick(true);
    }
    async createLevelPreCommon() {
        cc.log("createLevelPreCommon")
        let url = `prefab/level/LevelPre_Common`;
        let uiPfb = await ResManager.ins.loadRes(url, cc.Prefab, BUNDLE_TYPE_ENUM.MAIN);
        let levelPreCommon = cc.instantiate(uiPfb);
        levelPreCommon.parent = cc.find('Canvas/GameCommonLayer');
        return levelPreCommon;
    }
    removeLevelPreCommon() {
        cc.log("removeLevelPreCommon")
        let node = cc.find('Canvas/GameCommonLayer');
        let num = node.childrenCount;
        for (let i = 0; i < num; i++) {
            node.children[num - 1 - i].destroy();
        }
        node.removeAllChildren();
    }
    private async show(uiName: string, type: UI_TYPE_ENUM, bundleType: BUNDLE_TYPE_ENUM, ...args: Array<unknown>) {
        this.enabledClick(false);
        let url = `prefab/${this.getFolderName(type)}/${uiName}`;
        let uiPfb = await ResManager.ins.loadRes(url, cc.Prefab, bundleType);
        let node = cc.instantiate(uiPfb);
        node.parent = this.getUIParent(type);
        EventManager.ins.emit(EVENT_NAME_ENUM.OPEN_UI, ...args);

        if (type != UI_TYPE_ENUM.LOAD) {
            this.uiStack.push({ node, type });
        }

        if (type === UI_TYPE_ENUM.POP) {
            let uiContent = node.getChildByName("bg");
            Tools.popShowAnim(uiContent, () => {
                this.enabledClick(true);
            });
        } else {
            this.enabledClick(true);
        }

    }
    /** 展示全屏UI */
    showUI(uiName: string, bundleType: BUNDLE_TYPE_ENUM, ...args: Array<unknown>) {
        this.show(uiName, UI_TYPE_ENUM.UI, bundleType, ...args);
    }
    /** 展示弹窗 */
    showPop(uiName: string, bundleType: BUNDLE_TYPE_ENUM, ...args: Array<unknown>) {
        this.show(uiName, UI_TYPE_ENUM.POP, bundleType, ...args);
    }

    /** 关闭最上层 */
    close(...args: Array<unknown>) {
        if (this.uiStack.length <= 0) return;
        this.enabledClick(false);
        let IUI = this.uiStack.pop();

        EventManager.ins.emit(EVENT_NAME_ENUM.CLOSE_UI, ...args)

        let animTime = 0;
        if (IUI.type === UI_TYPE_ENUM.POP) {
            animTime = Tools.popCloseAnim(IUI.node.getChildByName("bg"), () => {
                IUI.node.destroy();
                IUI = null;
                this.enabledClick(true);
            });
        } else {
            // cc.log('close', IUI.node.name)
            if (IUI.node.name.includes("LevelPre_")) {
                this.removeLevelPreCommon();
            }

            IUI.node.destroy();
            IUI = null;
            this.enabledClick(true);
        }

        return animTime;
    }

    /** 关闭所有UI */
    closeAll() {
        let animTime = 0;
        this.uiStack.find(i => {
            let newTime = this.close();
            animTime = Math.max(animTime, newTime)
        });
        this.uiStack.length = 0;
        return animTime;
    }

    /** 接收全屏触摸吗 */
    enabledClick(enabled: boolean) {
        if (!this.blockLayer)
            this.blockLayer = cc.find('Canvas/' + blockLayerName);
        this.blockLayer.active = !enabled;
    }
    /** 接收游戏内触摸吗 */
    enabledGameClick(enabled: boolean) {
        cc.log("%c 当前是否可触摸：" + enabled, "color:red;")
        if (!this.blockGameLayer)
            this.blockGameLayer = cc.find('Canvas/' + blockGameLayerName);
        this.blockGameLayer.active = !enabled;
    }


    /** 显示提示文字 */
    async showToast(_text: string) {
        cc.log("showToast: " + _text)
        let prefab = await ResManager.ins.loadRes("prefab/node/toast", cc.Prefab, BUNDLE_TYPE_ENUM.MAIN);
        let node = cc.instantiate(prefab);
        node.parent = cc.find('Canvas');
        node.setSiblingIndex(200)
        node.getComponentInChildren(cc.Label).string = _text;

        //action
        cc.tween(node)
            .delay(1.3)
            .to(1, { opacity: 0 }, { easing: cc.easing.quintOut })
            .start();

        cc.tween(node)
            .to(1, { position: cc.v3(0, 200) }, { easing: cc.easing.quintOut })
            .delay(0.3)
            .to(1, { position: cc.v3(0, - 50) }, { easing: cc.easing.quintOut })
            .call((node: cc.Prefab) => node.destroy())
            .start();
    }

    private getFolderName(type: UI_TYPE_ENUM) {
        let folder = "ui";
        switch (type) {
            case UI_TYPE_ENUM.UI:
                folder = "ui"
                break;
            case UI_TYPE_ENUM.POP:
                folder = "ui"
                break;
            case UI_TYPE_ENUM.LOAD:
                folder = "ui"
                break;
            default:
                break;
        }
        return folder;
    }
    private getUIParent(type: UI_TYPE_ENUM) {
        let parentName = "Canvas";
        switch (type) {
            case UI_TYPE_ENUM.UI:
                parentName += "/UILayer"
                break;
            case UI_TYPE_ENUM.POP:
                parentName += "/PopLayer"
                break;
            case UI_TYPE_ENUM.LOAD:
                parentName += "/" + loadLayerName
                break;
            default:
                break;
        }
        return cc.find(parentName);
    }
}